---
slug: /ci/quickstart/daggerize
title: "Daggerize an example application"
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Dagger for CI: Quickstart

## Daggerize an example application

The best way to understand how Dagger works is by creating a delivery pipeline using Dagger Functions - a process we call "Daggerizing".

:::tip DAGGERIZING
1. Choose a Dagger SDK and bootstrap a new Dagger module for your application's pipeline with `dagger init`.
2. Construct the pipeline by creating and combining one or more Dagger Functions to produce the desired results. Your Dagger Functions can use the core Dagger API and/or call Dagger Functions from third-party Daggerverse modules.
3. Use `dagger call` to run and test your pipeline locally. Once you're satisfied, transfer your Dagger module and your `dagger call` commands to your CI configuration.
:::

### Get the example application

The example application is a skeleton Vue framework application that returns a "Hello from Dagger!" welcome page. Clone its repository and set it as the current working directory:

```shell
git clone https://github.com/dagger/hello-dagger
cd hello-dagger
```

### Visualize in Dagger Cloud (optional)

:::important
This step is optional and will create a Dagger Cloud individual plan account. The individual plan is free of charge for a single user. You will require a GitHub account for account setup and identity verification. If you prefer not to sign up for Dagger Cloud, you can skip this section.
:::

Dagger Cloud is an online visualization tool for Dagger pipelines. It provides a web interface to visualize each step of your pipeline, drill down to detailed logs, understand how long operations took to run, and whether operations were cached.

Create a new Dagger Cloud account by running `dagger login`:

```shell
dagger login
```

The Dagger CLI will invite you to authenticate your device by displaying a link containing a unique key. Click the link in your browser, and verify that you see the same key in the Dagger Cloud Web interface.

```shell
$ dagger login
Browser opened to: https://auth.dagger.cloud/activate?user_code=FCNP-SRLM
Confirmation code: FCNP-SRLM
```

Once you confirm your authentication code, your Dagger CLI will be authenticated and you will get redirected to your newly created Dagger Cloud organization.

After successfully creating your organization, all future `dagger call` pipelines
can be inspected in Dagger Cloud.

### Initialize a Dagger module

Bootstrap a new Dagger module in Go, Python, TypeScript, PHP, or Java by running `dagger init` in the application's root directory, using the `--source` flag to specify a directory for the module's source code.

<Tabs groupId="language">
<TabItem value="Go">

```shell
dagger init --sdk=go --source=./dagger
```

This will generate a `dagger.json` module metadata file, an initial `dagger/main.go` source code template, as well as a `dagger/dagger.gen.go` file and `dagger/internal/` directory.
</TabItem>
<TabItem value="Python">

```shell
dagger init --sdk=python --source=./dagger
```

This will generate a `dagger.json` module metadata file, initial `dagger/src/hello_dagger/__init__.py`  and `dagger/src/hello_dagger/main.py` source code template, `dagger/pyproject.toml` and `dagger/uv.lock` files, as well as a generated `dagger/sdk` folder for local development.
</TabItem>
<TabItem value="TypeScript">

```shell
dagger init --sdk=typescript --source=./dagger
```

This will generate a `dagger.json` module metadata file, initial `dagger/src/index.ts` source code template, `dagger/package.json` and `dagger/tsconfig.json` files, as well as a generated `dagger/sdk` folder for local development.
</TabItem>
<TabItem value="PHP">

```shell
dagger init --sdk=php --source=./dagger
```

This will generate a `dagger.json` module metadata file, initial `dagger/src/HelloDagger.php` source code template, `dagger/composer.json`, `dagger/composer.lock` and `dagger/entrypoint.php` files, as well as a generated `dagger/sdk` folder for local development.
</TabItem>
<TabItem value="Java">

```shell
dagger init --sdk=java --source=./dagger
```

This will generate a `dagger.json` module metadata file, initial `dagger/src/main/java/io/dagger/modules/hellodagger/HelloDagger.java` source code template, `dagger/pom.xml` file for module dependencies, as well as a generated `dagger/target` folder for local development.
</TabItem>
</Tabs>

:::important
By default, the Dagger module name is automatically generated from the name of the directory in which `dagger init` runs. In this case, the default name of the cloned application directory is `hello-dagger`, so the module name is `HelloDagger`. If you cloned the application into a different directory, add the `--name=hello-dagger` flag to `dagger init` to correctly set the Dagger module name.
:::

### Construct a pipeline using Dagger Functions

Dagger Functions are regular code, written in Go, Python, TypeScript, PHP, or Java using the corresponding Dagger SDK. They consist of a series of method/function calls, such as "pull a container image", "copy a file", "forward a TCP port", and so on, which can be chained together.

:::note
Don't worry about how the Dagger Functions shown below work for the moment - it's explained in detail in  the next sections!
:::

<Tabs groupId="language">
<TabItem value="Go">

Replace the generated `dagger/main.go` file with the following code, which adds four Dagger Functions to your Dagger module:

```go file=./snippets/daggerize/go/main.go
```

In this Dagger module, each Dagger Function performs a different operation:

- The `Publish()` Dagger Function tests, builds and publishes a container image of the application to a registry.
- The `Test()` Dagger Function runs the application's unit tests and returns the results.
- The `Build()` Dagger Function performs a multi-stage build and returns a final container image with the production-ready application and an NGINX Web server to host and serve it.
- The `BuildEnv()` Dagger Function creates a container with the build environment for the application.

</TabItem>
<TabItem value="Python">

Replace the generated `dagger/src/hello_dagger/main.py` file with the following code, which adds four Dagger Functions to your Dagger module:

```python file=./snippets/daggerize/python/__init__.py
```

In this Dagger module, each Dagger Function performs a different operation:

- The `publish()` Dagger Function tests, builds and publishes a container image of the application to a registry.
- The `test()` Dagger Function runs the application's unit tests and returns the results.
- The `build()` Dagger Function performs a multi-stage build and returns a final container image with the production-ready application and an NGINX Web server to host and serve it.
- The `build_env()` Dagger Function creates a container with the build environment for the application.

</TabItem>
<TabItem value="TypeScript">

Replace the generated `dagger/src/index.ts` file with the following code, which adds four Dagger Functions to your Dagger module:

```typescript file=./snippets/daggerize/typescript/index.ts
```

In this Dagger module, each Dagger Function performs a different operation:

- The `publish()` Dagger Function tests, builds and publishes a container image of the application to a registry.
- The `test()` Dagger Function runs the application's unit tests and returns the results.
- The `build()` Dagger Function performs a multi-stage build and returns a final container image with the production-ready application and an NGINX Web server to host and serve it.
- The `buildEnv()` Dagger Function creates a container with the build environment for the application.

</TabItem>
<TabItem value="PHP">

Replace the generated `dagger/src/HelloDagger.php` file with the following code, which adds four Dagger Functions to your Dagger module:

```php file=./snippets/daggerize/php/src/HelloDagger.php
```

In this Dagger module, each Dagger Function performs a different operation:

- The `publish()` Dagger Function tests, builds and publishes a container image of the application to a registry.
- The `test()` Dagger Function runs the application's unit tests and returns the results.
- The `build()` Dagger Function performs a multi-stage build and returns a final container image with the production-ready application and an NGINX Web server to host and serve it.
- The `buildEnv()` Dagger Function creates a container with the build environment for the application.

</TabItem>
<TabItem value="Java">

Replace the generated `dagger/src/main/java/io/dagger/modules/hellodagger/HelloDagger.java` file with the following code, which adds four Dagger Functions to your Dagger module:

```java file=./snippets/daggerize/java/src/main/java/io/dagger/modules/hellodagger/HelloDagger.java
```

In this Dagger module, each Dagger Function performs a different operation:

- The `publish()` Dagger Function tests, builds and publishes a container image of the application to a registry.
- The `test()` Dagger Function runs the application's unit tests and returns the results.
- The `build()` Dagger Function performs a multi-stage build and returns a final container image with the production-ready application and an NGINX Web server to host and serve it.
- The `buildEnv()` Dagger Function creates a container with the build environment for the application.

</TabItem>
</Tabs>

:::tip IDE SUPPORT
If you're writing the code above in an IDE, you can easily [configure your IDE to recognize your Dagger module](../../api/ide-integration.mdx). This can significantly speed things up, by giving you automatic type-checking, intelligent code completion, and other IDE features when writing Dagger module code.
:::

:::warning
The Dagger module's class name is automatically generated based on the name of the directory where `dagger init` was executed. If you cloned the example application into a directory other than the default (`hello-dagger`), or if you used a different TypeScript application altogether, the auto-generated class name will be different and the code samples above will not work until you update them to use the correct name. Alternatively, you can override Dagger's default class name by specifying a name via the `--name` argument to `dagger init`.
:::

### Run the pipeline

Call a Dagger Function to run the pipeline:

```shell
dagger call publish --source=.
```

This single command runs the application's tests, then builds and publishes it as a container image to the [ttl.sh container registry](https://ttl.sh). Here's what you should see:

![Publish](/img/current_docs/quickstart/publish.gif)

If you signed up for Dagger Cloud, the output of the previous command would have also included a link to visualize the pipeline run on Dagger Cloud. Click the link in your browser to see a complete breakdown  of the steps performed by the pipeline. Here's what you should see:

![login](/img/current_docs/quickstart/trace.gif)

This is called a "Trace". It represents a single run of a Daggerized pipeline, and shows a detailed log and output of each step in the pipeline. If there are any errors in the run, Dagger Cloud automatically brings you to the first error in the list.

:::tip DID YOU NOTICE...
1. Even though you just tested, built and published a Node.js application, you didn't need to install any dependencies like `node` or `npm` on your local machine. You only needed the Dagger CLI and the ability to run containers. This is a very powerful feature that eliminates all the variability and dependencies related to the host environment and/or configuration.
1. Subsequent calls to `dagger call publish...` are significantly faster than the first run (try it!). Dagger caches every operation by default and automatically generates a [Directed Acyclic Graph (DAG)](https://en.wikipedia.org/wiki/Directed_acyclic_graph) to run your pipeline steps concurrently to maximize pipeline speed and accuracy.
:::
